package wang.conge.javasedemo.core.thread;

import java.util.Arrays;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;

public class RecursiveActionTest {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		//创建ForkJoinPool线程池,原理则是返回一个ForkJoinPool的实例
		ForkJoinPool  forkjoinPool = new ForkJoinPool();
		
		int[] nums = {0,1,2,3,4,5,6,7,8};
		
//		forkjoinPool.submit(new NumPrintRecursiveAction(nums));
		
		Future<Integer> future = forkjoinPool.submit(new NumCountRecursiveAction(nums));
		System.out.println(future.get());
		
		forkjoinPool.awaitTermination(2, TimeUnit.SECONDS);
	}
	
	static class NumPrintRecursiveAction extends RecursiveAction{
		private static final long serialVersionUID = 1L;
		private int[] nums;
		
		public NumPrintRecursiveAction(int[] nums){
			this.nums = nums;
		}
		
		@Override
		protected void compute() {
			//如果数组的length小于4，直接执行
			if(nums.length<4){
				for(int num:nums){
					System.out.println(num);
				}
				return;
			}
			
			//如果当前数组的length大于4，分成两个任务继续执行
			int mid = nums.length/2;
			
			int[] numsLeft = Arrays.copyOfRange(nums, 0, mid);
			int[] numsRight = Arrays.copyOfRange(nums, mid, nums.length);
			
			NumPrintRecursiveAction left = new NumPrintRecursiveAction(numsLeft);
			NumPrintRecursiveAction right = new NumPrintRecursiveAction(numsRight);
			
			//并发执行两个子任务
			left.fork();
			right.fork();
		}
		
	}
	
	static class NumCountRecursiveAction extends RecursiveTask<Integer>{
		private static final long serialVersionUID = 1L;
		private int[] nums;
		
		public NumCountRecursiveAction(int[] nums){
			this.nums = nums;
		}
		
		@Override
		protected Integer compute() {
			//如果数组的length小于4，直接执行
			if(nums.length<4){
				int total = 0;
				for(int num:nums){
					total = total + num;
				}
				return total;
			}
			
			//如果当前数组的length大于4，分成两个任务继续执行
			int mid = nums.length/2;
			
			int[] numsLeft = Arrays.copyOfRange(nums, 0, mid);
			int[] numsRight = Arrays.copyOfRange(nums, mid, nums.length);
			
			NumCountRecursiveAction left = new NumCountRecursiveAction(numsLeft);
			NumCountRecursiveAction right = new NumCountRecursiveAction(numsRight);
			
			//并发执行两个子任务
			left.fork();
			right.fork();
			
			//汇总结果
			return left.join() + right.join();
		}
		
	}
}
